﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using OBUCare.Core.Common;
using System.Collections;

namespace OBUCare.Web
{


    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        private static Queue LogQueue = new Queue();
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            //在应用程序启动时运行的代码

            //启动log4Net
            log4net.Config.XmlConfigurator.Configure();

            #region  多线程监听并处理异常
            //多线程处理日志模式。
            System.Threading.ThreadPool.QueueUserWorkItem(a =>
            {
                //无限循环监听错误队列有无错误
                while (true)
                {
                    try
                    {
                        //如果队列中有错误
                        if (LogQueue.Count > 0)
                        {
                            //转换成Exception
                            var exception = LogQueue.Dequeue() as Exception;
                            //再次判断
                            if (exception != null)
                            {
                                //通过log4Net，写入系统
                                TraceHelper.TraceError(exception.ToString());
                            }
                            else
                            {
                                //如果没有，就让线程休息30毫秒
                                System.Threading.Thread.Sleep(30);
                            }
                        }
                        else
                        {
                            //休息30毫秒
                            System.Threading.Thread.Sleep(30);
                        }
                    }
                    catch (InvalidOperationException ex)
                    {
                        //这个异常是上面的Try住的异常，是队列本身问题，不需要计入系统日志
                        continue;
                    }
                    catch (Exception ex2)
                    {
                        //这个是除了InvalidOperationException这个类型的异常都要继续加入队列，继续处理
                        LogQueue.Enqueue(ex2);
                    }

                }
            }, null);
            #endregion
        }


        /// <summary>
        /// 处理没有被处理过的异常
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender, EventArgs e)
        {
            //在出现未处理的错误时运行的代码

            // 1.记录错误日志信息。
            LogQueue.Enqueue(Server.GetLastError());



            //this.Response.Clear();//这里是关键，清除在返回前已经设置好的标头信息，这样后面的跳转才不会报错
            //this.Response.BufferOutput = true;//设置输出缓冲
            //if (!this.Response.IsRequestBeingRedirected)//在跳转之前做判断,防止重复
            //{
            //    this.Response.Redirect("~/Error.html", true);
            //}

            // 2.跳转到错误页面。
            Response.Redirect("~/Error.html");
        }

        //This method checks if we have an AJAX request or not
        private bool IsAjaxRequest()
        {
            //The easy way
            bool isAjaxRequest = (Request["X-Requested-With"] == "XMLHttpRequest")
            || ((Request.Headers != null)
            && (Request.Headers["X-Requested-With"] == "XMLHttpRequest"));

            //If we are not sure that we have an AJAX request or that we have to return JSON 
            //we fall back to Reflection
            if (!isAjaxRequest)
            {
                try
                {
                    //The controller and action
                    string controllerName = Request.RequestContext.
                                            RouteData.Values["controller"].ToString();
                    string actionName = Request.RequestContext.
                                        RouteData.Values["action"].ToString();

                    //We create a controller instance
                    DefaultControllerFactory controllerFactory = new DefaultControllerFactory();
                    Controller controller = controllerFactory.CreateController(
                    Request.RequestContext, controllerName) as Controller;

                    //We get the controller actions
                    ReflectedControllerDescriptor controllerDescriptor =
                    new ReflectedControllerDescriptor(controller.GetType());
                    ActionDescriptor[] controllerActions =
                    controllerDescriptor.GetCanonicalActions();

                    //We search for our action
                    foreach (ReflectedActionDescriptor actionDescriptor in controllerActions)
                    {
                        if (actionDescriptor.ActionName.ToUpper().Equals(actionName.ToUpper()))
                        {
                            //If the action returns JsonResult then we have an AJAX request
                            if (actionDescriptor.MethodInfo.ReturnType
                            .Equals(typeof(JsonResult)))
                                return true;
                        }
                    }
                }
                catch
                {

                }
            }

            return isAjaxRequest;
        }

    }
}